package student.mindmap.controller;

import javafx.application.Platform;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.CubicCurve;
import javafx.scene.shape.QuadCurve;
import javafx.stage.FileChooser;
import student.mindmap.core.model.MindMap;
import student.mindmap.core.model.MindMapNode;
import student.mindmap.core.model.MindMapPersistence;
import student.mindmap.core.model.MindMapTreeCall;
import student.mindmap.utils.Log;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Queue;
import java.util.*;

import static student.mindmap.utils.Log.showSimpleAlert;

public class FirstController {

    // 当前思维导图数据模型
    private MindMap currentMap;
    // 当前选中的节点
    private MindMapNode selectedNode;
    // 当前选中的布局
    private LayoutType currentLayout = LayoutType.RIGHT;
    // 布局类型枚举
    private enum LayoutType {LEFT, RIGHT, AUTO}

    /* 常量配置 */
    private static final double HORIZONTAL_SPACING = 120; // 水平间距
    private static final double VERTICAL_SPACING = 80;    // 垂直间距

    /* FXML注入的UI组件 */
    @FXML private Pane canvasPane;
    @FXML private ScrollPane canvasScrollPane;  // 主画布容器
    @FXML private ColorPicker nodeColorPicker;  // 节点颜色选择器
    @FXML private Spinner<Integer> nodeSizeSpinner; // 字号选择器
    @FXML private TextField nodeWidthInput;     // 节点宽度输入框
    @FXML private Label mapTitle;    // 导图标题显示


    /**
     * 初始化样式控制组件
     * 设置默认值和事件监听
     */
    private void initializeStyleControls() {
        // 颜色选择器初始化
        nodeColorPicker.setValue(Color.rgb(75, 255, 172));
        nodeColorPicker.setOnAction(e -> {
            refreshLayout();
        });

        // 字号选择器初始化
        nodeSizeSpinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(10, 30, 14));
        nodeSizeSpinner.valueProperty().addListener((obs, oldVal, newVal) -> {
            refreshLayout();
        });

        // 节点宽度输入初始化
        nodeWidthInput.setText("80");
        nodeWidthInput.textProperty().addListener((obs, oldVal, newVal) -> {
            try {
                int width = Integer.parseInt(newVal);
                if (width > 0) {
                    refreshLayout();
                } else {
                    nodeWidthInput.setText(oldVal);
                }
            } catch (NumberFormatException ex) {
                nodeWidthInput.setText(oldVal);
            }
        });
    }

     /**
      * 更新所有节点样式
      * 同步数据模型到视图层
      */
     private void updateAllNodeStyles() {
         double nodeWidth = Double.parseDouble(nodeWidthInput.getText());
         Color nodeColor = nodeColorPicker.getValue();
         int fontSize = nodeSizeSpinner.getValue();

         // 使用BFS遍历更新所有现有节点
         Queue<MindMapNode> queue = new LinkedList<>();
         queue.addAll(currentMap.getAllNodes());
         while (!queue.isEmpty()) {
             MindMapNode node = queue.poll();
             Node button = findButtonByNode(node);
             if (button != null) {
                 button.setStyle(String.format(
                         "-fx-background-color: %s; -fx-font-size: %dpx; -fx-min-width: %fpx;",
                         toHexString(nodeColor), fontSize, nodeWidth
                 ));
             }
             queue.addAll(node.getChildren());
         }

         // 设置新节点默认样式
         MindMapNode.setDefaultStyle(nodeColor, fontSize, nodeWidth);
     }

    /**
     * 根据节点对象查找对应的UI控件
     * @param node 数据模型节点
     * @return 对应的Button控件
     */
    private Node findButtonByNode(MindMapNode node) {
        for (Node n : canvasPane.getChildren()) {
            if (n instanceof Button) {
                Button btn = (Button)n;
                System.out.println("Checking node: " + btn.getText()
                        + " at (" + btn.getLayoutX() + "," + btn.getLayoutY() + ")"
                        + " size: " + btn.getWidth() + "x" + btn.getHeight());
                if (btn.getText().equals(node.getText())) {
                    return n;
                }
            }
        }
        return null;
    }


    private void applyNodeStyle(Button nodeElement) {
        nodeElement.setStyle(
                "-fx-background-color: " + toHexString(MindMapNode.getDefaultColor()) +
                        "; -fx-font-size: " + MindMapNode.getDefaultFontSize() + "px;" +
                        "; -fx-min-width: " + MindMapNode.getDefaultWidth() + "px;" +
                "; -fx-padding: 4px;"               // 默认内边距
        );
    }

    /* 辅助工具方法 */

    /**
     * 将Color对象转换为HEX字符串
     * @param color JavaFX颜色对象
     * @return HEX格式字符串（#RRGGBB）
     */
    private String toHexString(Color color) {
        return String.format("#%02X%02X%02X",
                (int)(color.getRed() * 255),
                (int)(color.getGreen() * 255),
                (int)(color.getBlue() * 255)
        );
    }


    @FXML
    public void initialize() {
        initializeStyleControls();
        createNewMap();
        initializeOutline(currentMap.getRoot());
        outlineTree.setCellFactory(tv -> new MindMapTreeCall());
        canvasPane.setOnMouseClicked(e -> {
            if (e.getTarget() == canvasPane) {
                selectedNode = null;     // 清空选中节点
                refreshOutline();        // 更新大纲结构
            }
        });

        // 应用CSS样式
        outlineTree.getStylesheets().add(
                Objects.requireNonNull(getClass().getResource("/mindmap.css")).toExternalForm()
        );

        // 添加快捷键
        canvasPane.sceneProperty().addListener((obs, oldScene, newScene) -> {
            if (newScene != null) {
                addGlobalShortcuts(newScene);
            }
        });
        canvasScrollPane.viewportBoundsProperty().addListener((obs, oldBounds, newBounds) -> {
            canvasPane.setPrefWidth(newBounds.getWidth());
            canvasPane.setPrefHeight(newBounds.getHeight());
        });

    }

    //快捷键
    private void addGlobalShortcuts(Scene scene) {
        scene.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
            if (event.isControlDown()) {
                switch (event.getCode()) {
                    case N -> {
                        createNewMap();
                        event.consume();
                    }
                    case S -> {
                        if (event.isShiftDown()) {
                            handleResave(null);  // 另存为：Ctrl + Shift + S
                        } else {
                            handleSave(null);    // 保存：Ctrl + S
                        }
                        event.consume();
                    }
                    case E -> {
                        handleExport(null);     // 导出：Ctrl + E
                        event.consume();
                    }
                    case Z -> {
                        handleUndo(null);       //  撤销：Ctrl + Z
                        event.consume();
                    }
                    case Y -> {
                        handleRedo(null);       //  重做：Ctrl + Y
                        event.consume();
                    }
                    case ADD, EQUALS -> {           // 添加子节点：Ctrl+= 或 Ctrl+加号
                        handleAddChild();
                        event.consume();
                    }
                    case DELETE, BACK_SPACE -> {    // 删除节点：Ctrl+Delete 或 Ctrl+Backspace
                        handleDeleteNode(selectedNode);
                        event.consume();
                    }
                    case O -> {
                        handleOpen(null);  // 打开文件：Ctrl + O
                        event.consume();
                    }
                }
            }
        });
    }

    // 新建思维导图
    @FXML
    private void createNewMap() {
        currentMap = new MindMap();
        currentMap.createNewMap("中心主题");
        mapTitle.setText("中心主题");
        selectedNode = currentMap.getRoot();
        // 应用当前样式设置
        MindMapNode.setDefaultStyle(
                nodeColorPicker.getValue(),
                nodeSizeSpinner.getValue(),
                Double.parseDouble(nodeWidthInput.getText())
        );
        refreshLayout();
        refreshOutline();
    }




    /* 布局渲染相关方法 */

    /**
     * 刷新整个画布布局
     * 根据当前布局类型重新渲染所有节点
     */
    private void refreshLayout() {
        if (currentMap == null) return;
        canvasPane.getChildren().clear();

        // 渲染中心节点
        switch (currentLayout) {
            case LEFT -> renderLeftNode(currentMap.getRoot(), 400, 300, 0);
            case RIGHT -> renderNode(currentMap.getRoot(), 400, 300, 0);
            case AUTO -> renderAutoNode(currentMap.getRoot(), 400, 300, 0, true,null,10);
        }
        updateAllNodeStyles();
    }


    @FXML
    private void handleLeftLayout(ActionEvent event) {
        currentLayout = LayoutType.LEFT;
        refreshLayout();
        updateLayoutButtonStyle();
    }

    @FXML
    private void handleRightLayout(ActionEvent event) {
        currentLayout = LayoutType.RIGHT;
        refreshLayout();
        updateLayoutButtonStyle();
    }

    @FXML
    private void handleAutoLayout(ActionEvent actionEvent) {
        currentLayout = LayoutType.AUTO;
        refreshLayout();
        updateLayoutButtonStyle();
    }

    //将选择的布局变成高亮的方法
    @FXML
    private MenuItem leftLayoutButton;
    @FXML
    private MenuItem rightLayoutButton;
    @FXML
    private MenuItem autoLayoutButton;


    private void updateLayoutButtonStyle() {
        // 清空样式
        leftLayoutButton.setStyle("");
        rightLayoutButton.setStyle("");
        autoLayoutButton.setStyle("");

        // 给当前选择的布局加深颜色
        switch (currentLayout) {
            case LEFT -> leftLayoutButton.setStyle("-fx-background-color: #90CAF9;");
            case RIGHT -> rightLayoutButton.setStyle("-fx-background-color: #90CAF9;");
            case AUTO -> autoLayoutButton.setStyle("-fx-background-color: #90CAF9;");
        }
    }

    /**
     * 自动布局算法实现
     * @param node 当前节点
     * @param x 中心坐标X
     * @param y 中心坐标Y
     * @param depth 节点深度
     * @param isRoot 是否根节点
     * @param goLeft 布局方向
     * @param maxDepth 最大深度
     */
    private void renderAutoNode(MindMapNode node, double x, double y, int depth, boolean isRoot, Boolean goLeft,int maxDepth) {
        Button nodeElement = new Button(node.getText());
        applyNodeStyle(nodeElement);
        canvasPane.getChildren().add(nodeElement);



        Platform.runLater(() -> {
            nodeElement.setLayoutX(x - nodeElement.getWidth() / 2);
            nodeElement.setLayoutY(y - nodeElement.getHeight() / 2);
        });

        final MindMapNode targetNode = node;

        if (node == selectedNode) {
            nodeElement.setStyle(
                    nodeElement.getStyle() +
                            "; -fx-border-color: #2196F3;" +     // 边框颜色
                            "; -fx-border-width: 2px;" +         // 边框宽度
                            "; -fx-border-radius: 8px;" +        // 圆角半径
                            "; -fx-padding: 6px;"               // 内边距
            );
        }

        // 计算所有节点文本长度总和
        int totalTextLength = currentMap.getAllNodes().stream()
                .mapToInt(nodes -> node.getText().length())
                .sum();
        // 根据文本长度总和等因素调整水平间距
        double adjustedHorizontalSpacing = HORIZONTAL_SPACING * (totalTextLength / 100.0 + 1);
        // 垂直间距同理根据实际情况调整


        List<MindMapNode> children = node.getChildren();


        // 根节点交替分布子节点，非根节点传递布局方向
        List<MindMapNode> leftChildren = new ArrayList<>();
        List<MindMapNode> rightChildren = new ArrayList<>();

        if (isRoot) {
            int childCount= children.size();
            int leftCount=childCount/2+(childCount%2);
            // 对于根节点，更均匀地分配子节点
            for (int i = 0; i < childCount; i++) {
                MindMapNode child=children.get(i);
                if (i <leftCount) {
                    leftChildren.add(children.get(i));
                    child.setLayoutToLeft(true);
                } else {
                    rightChildren.add(children.get(i));
                    child.setLayoutToLeft(false);
                }
            }
        } else {
            // 使用记忆的方向，如果没有则用传参
            if (goLeft == null && node.getLayoutToLeft() != null) {
                goLeft = node.getLayoutToLeft();
            }

            if (goLeft != null) {
                if (goLeft) {
                    for (MindMapNode child : children) {
                        leftChildren.add(child);
                        child.setLayoutToLeft(true);
                    }
                } else {
                    for (MindMapNode child : children) {
                        rightChildren.add(child);
                        child.setLayoutToLeft(false);
                    }
                }
            } else {
                // 默认放右边
                for (MindMapNode child : children) {
                    rightChildren.add(child);
                    child.setLayoutToLeft(false);
                }
            }
        }


        // 渲染左侧子节点
        double startYLeft = y - (leftChildren.size() - 1) * VERTICAL_SPACING / 2;
        for (int i = 0; i < leftChildren.size(); i++) {
            MindMapNode child = leftChildren.get(i);
            //以传入的x为基准计算子节点水平位置
            double childX = x - HORIZONTAL_SPACING;
            double childY = startYLeft + i * VERTICAL_SPACING;

            renderAutoNode(child, childX, childY, depth + 1, false, true,10);

            QuadCurve connection = new QuadCurve(
                    x + nodeElement.getWidth() / 2, y + nodeElement.getHeight() / 2,
                    (x + childX) / 2, y + nodeElement.getHeight() / 2,
                    childX + nodeElement.getWidth() / 2, childY + nodeElement.getHeight() / 2
            );
            connection.setStrokeWidth(1.5);
            connection.setStroke(Color.web("#90CAF9"));
            connection.setFill(null);
            canvasPane.getChildren().add(0, connection);
        }

        // 渲染右侧子节点
        double startYRight = y - (rightChildren.size() - 1) * VERTICAL_SPACING / 2;
        for (int i = 0; i < rightChildren.size(); i++) {
            MindMapNode child = rightChildren.get(i);
            double childX = x + HORIZONTAL_SPACING;
            double childY = startYRight + i * VERTICAL_SPACING;

            renderAutoNode(child, childX, childY, depth + 1, false, false,10);

            QuadCurve connection = new QuadCurve(
                    x + nodeElement.getWidth() / 2, y + nodeElement.getHeight() / 2,
                    (x + childX) / 2, y + nodeElement.getHeight() / 2,
                    childX + nodeElement.getWidth() / 2, childY + nodeElement.getHeight() / 2
            );
            connection.setStrokeWidth(1.5);
            connection.setStroke(Color.web("#90CAF9"));
            connection.setFill(null);

            canvasPane.getChildren().add(0, connection);
        }

        // 上下文菜单和点击事件（保持不变）
        ContextMenu contextMenu = new ContextMenu();
        MenuItem deleteItem = new MenuItem("删除");
        deleteItem.setOnAction(e -> handleDeleteNode(targetNode));
        MenuItem addChildItem = new MenuItem("添加子节点");
        addChildItem.setOnAction(e -> handleAddChild());
        MenuItem addSiblingItem = new MenuItem("添加兄弟节点");
        addSiblingItem.setOnAction(e -> handleAddSibling());
        contextMenu.getItems().addAll(addChildItem, addSiblingItem, deleteItem);
        nodeElement.setContextMenu(contextMenu);

        nodeElement.setOnMouseClicked(e -> {
                    if (e.getButton() == MouseButton.PRIMARY) {
                        if (e.getClickCount() == 2) {
                            showTextEditDialog(node);
                            refreshLayout(); // 使用统一的刷新方法
                        } else if (e.getClickCount() == 1) {
                            selectedNode = targetNode;
                            refreshLayout();
                            refreshOutline();
                        }
                        e.consume();
                    }
                }
        );
        updateAllNodeStyles();
    }



    //新建节点，右侧布局
    private void renderNode(MindMapNode node, double x, double y, int depth) {
        Button nodeElement = new Button(node.getText());
        applyNodeStyle(nodeElement);


        // 设置根节点位置
        if (depth == 0) {
            nodeElement.setLayoutX(400 - nodeElement.getWidth() / 2);
            nodeElement.setLayoutY(300 - nodeElement.getHeight() / 2);
        } else {
            nodeElement.setLayoutX(x - nodeElement.getWidth() / 2);
            nodeElement.setLayoutY(y - nodeElement.getHeight() / 2);
         }
        canvasPane.getChildren().add(nodeElement);
        // 在 renderNode 方法开头清理旧连接线
        canvasPane.getChildren().removeIf(node1 -> node1 instanceof CubicCurve);

        final MindMapNode targetNode = node;

        if (node == selectedNode) {
            nodeElement.setStyle(
                    nodeElement.getStyle() +
                            "; -fx-border-color: #2196F3;" +
                            "; -fx-border-width: 2px;" +
                            "; -fx-border-radius: 8px;" +
                            "; -fx-padding: 6px;"
            );
        }

        List<MindMapNode> children = node.getChildren();
        double childX = x + HORIZONTAL_SPACING;
        double childY = y - (children.size() - 1) * VERTICAL_SPACING / 2;

        // 先渲染所有子节点
        // 修改后的子节点遍历逻辑（renderNode方法内）
        for (MindMapNode child : children) {
            renderNode(child, childX, childY, depth + 1);
            Button childButton = (Button) findButtonByNode(child);
            if (childButton != null) {
                // 直接计算连接线
                double startX = x + nodeElement.getWidth();
                double startY = y + nodeElement.getHeight() / 2;
                double endX = childX;
                double endY = childY + childButton.getHeight() / 2;
                // 使用QuadCurve
                QuadCurve connection = new QuadCurve(
                        startX, startY,
                        (startX + endX) / 2, (startY + endY) / 2,
                        endX, endY
                );
                connection.setStroke(Color.web("#90CAF9"));
                canvasPane.getChildren().add(connection);
            }
            childY += VERTICAL_SPACING;
        }
        updateAllNodeStyles();
        setupNodeInteraction(nodeElement, targetNode);
    }

    //左侧布局
    private void renderLeftNode(MindMapNode node, double x, double y, int depth) {
        Button nodeElement = new Button(node.getText());
        applyNodeStyle(nodeElement);
        nodeElement.setLayoutX(x - nodeElement.getWidth() / 2);
        nodeElement.setLayoutY(y - nodeElement.getHeight() / 2);

        canvasPane.getChildren().add(nodeElement);

        final MindMapNode targetNode = node;

        if (node == selectedNode) {
            nodeElement.setStyle(
                    nodeElement.getStyle() +
                            "; -fx-border-color: #2196F3;" +     // 边框颜色
                            "; -fx-border-width: 2px;" +         // 边框宽度
                    "; -fx-border-radius: 8px;" +        // 圆角半径
                    "; -fx-padding: 6px;"               // 内边距
            );
        }

        List<MindMapNode> children = node.getChildren();
        double childX = x - HORIZONTAL_SPACING;
        double childY = y - (children.size() - 1) * VERTICAL_SPACING / 2;

        for (MindMapNode child : children) {
            renderLeftNode(child, childX, childY, depth + 1);

            // 计算连接线的起点和终点
            double startX = x + nodeElement.getWidth() / 2;
            double startY = y + nodeElement.getHeight() / 2;
            double endX = childX - nodeElement.getWidth() / 2; // 假设子节点的宽度为 nodeElement.getWidth()
            double endY = childY + nodeElement.getHeight() / 2; // 假设子节点的高度为 nodeElement.getHeight()

            // 使用 QuadCurve 绘制连接线
            QuadCurve connection = new QuadCurve(
                    startX, startY,
                    (startX + endX) / 2, startY,
                    endX, endY
            );
            connection.setStrokeWidth(1.5);
            connection.setStroke(Color.web("#90CAF9"));
            connection.setFill(null);
            canvasPane.getChildren().add(connection);

            childY += VERTICAL_SPACING;
        }
        updateAllNodeStyles();
        setupNodeInteraction(nodeElement, targetNode);
    }



    private void setupNodeInteraction(Button nodeElement, MindMapNode targetNode) {
        // 右键菜单
        ContextMenu contextMenu = new ContextMenu();
        MenuItem deleteItem = new MenuItem("删除");
        deleteItem.setOnAction(e -> handleDeleteNode(targetNode));
        MenuItem addChildItem = new MenuItem("添加子节点");
        addChildItem.setOnAction(e -> handleAddChild());
        MenuItem addSiblingItem = new MenuItem("添加兄弟节点");
        addSiblingItem.setOnAction(e -> handleAddSibling());
        contextMenu.getItems().addAll(addChildItem, addSiblingItem, deleteItem);
        nodeElement.setContextMenu(contextMenu);

        // 鼠标点击事件
        nodeElement.setOnMouseClicked(e -> {
            if (e.getButton() == MouseButton.PRIMARY) {
                if (e.getClickCount() == 2) {
                    showTextEditDialog(targetNode);
                    refreshLayout();
                } else if (e.getClickCount() == 1) {
                    selectedNode = targetNode;
                    refreshLayout();
                    refreshOutline();
                }
                e.consume();
            }
        });
    }




    private void handleDeleteNode(MindMapNode node) {
        pushState();//添加当前保存状态
        // 防御性编程：检查合法性
        if (node == null || node == currentMap.getRoot()) {
            Log.showAlert("操作警告",
                    "禁止删除",
                    "无法删除根节点");
            return;
        }

        // 执行删除操作
        try {
            MindMapNode parent = node.getParent();
            if (parent != null) {
                currentMap.deleteNode(node);

                // 更新选中状态
                if (selectedNode == node) {
                    selectedNode = parent; // 选中父节点
                }

                refreshLayout();
                refreshOutline();
            }
        } catch (Exception e) {
            showSimpleAlert("删除节点失败: " + e.getMessage());
        }
    }

    // 按钮事件处理
    @FXML
    private void handleAddSibling() {
        if (selectedNode != null) {
            MindMapNode newNode = new MindMapNode("兄弟节点");

            pushState();//添加当前保存状态

            // 自动设置初始位置（最终位置由布局算法决定）
            Point parentPos = selectedNode.getPosition();
            newNode.setPosition(new Point(
                    parentPos.x + 50,
                    parentPos.y + selectedNode.getChildren().size()*30
            ));
            selectedNode.addSibling(newNode);
            currentMap.registerNode(newNode);
            Platform.runLater(() -> {
                refreshLayout();
                refreshOutline();
            });
        }
    }

    @FXML
    private void handleAddChild() {
        if (selectedNode != null) {
            MindMapNode newChild = new MindMapNode("子节点");

            pushState();//添加当前保存状态

            // 自动设置初始位置（最终位置由布局算法决定）
            Point parentPos = selectedNode.getPosition();
            newChild.setPosition(new Point(
                    parentPos.x + 50,
                    parentPos.y + selectedNode.getChildren().size()*30
            ));

            selectedNode.addChild(newChild);
            currentMap.registerNode(newChild);
            // 强制刷新并等待渲染
            Platform.runLater(() -> {
                refreshLayout();
                canvasPane.applyCss();
                canvasPane.layout();
                refreshOutline();
            });
        }
    }



    // 文本编辑对话框
    private void showTextEditDialog(MindMapNode node) {
        TextInputDialog dialog = new TextInputDialog(node.getText());
        dialog.setTitle("编辑");
        dialog.setHeaderText("修改文本内容");
        dialog.getEditor().setPrefWidth(300);

        dialog.showAndWait().ifPresent(newText -> {
           // 检查节点是否唯一，避免误创建新节点

            MindMapNode existingNode = currentMap.findNodeByUniqueId(node.getId());
            if (existingNode != null) {
                existingNode.setText(newText);
                refreshLayout();
                refreshOutline();
            }

        });
    }

    @FXML private TreeView<String> outlineTree;

    public void initializeOutline(MindMapNode rootNode) {
        TreeItem<String> rootItem = createTreeItem(rootNode);
        rootItem.setExpanded(true); // 默认展开根节点
        outlineTree.setRoot(rootItem);
        outlineTree.setShowRoot(true);
    }

    private TreeItem<String> createTreeItem(MindMapNode mapNode) {
        TreeItem<String> item = new TreeItem<>(mapNode.getText());
        for (MindMapNode child : mapNode.getChildren()) {
            item.getChildren().add(createTreeItem(child));
        }
        return item;
    }

    public void refreshOutline() {
        MindMapNode currentRoot = currentMap.getRoot();// 获取当前根节点
        TreeItem<String> newRoot = createTreeItem(currentRoot);
        outlineTree.setRoot(newRoot);
        newRoot.setExpanded(true);

        // 自动展开前两级节点
        newRoot.getChildren().forEach(level1 -> {
            level1.setExpanded(true);
            level1.getChildren().forEach(level2 -> level2.setExpanded(true));
        });
    }


    //导出图片
    @FXML
    private void handleExport(ActionEvent actionEvent) {

        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("导出思维导图");
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("PNG 图片", "*.png"),
                new FileChooser.ExtensionFilter("JPEG 图片", "*.jpg")
        );

        File file = fileChooser.showSaveDialog(canvasPane.getScene().getWindow());

        if (file != null) {
            try {
                // 获取文件扩展名
                String extension = file.getName().substring(file.getName().lastIndexOf(".") + 1);

                // 创建画布快照
                WritableImage image = canvasPane.snapshot(new SnapshotParameters(), null);

                // 转换为BufferedImage
                BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);


                // 保存图片（jpeg不支持透明背景，需要区分是否为JPG）
                if (extension.equalsIgnoreCase("jpg") || extension.equalsIgnoreCase("jpeg")) {
                    // 创建 RGB 图像，填充白底
                    BufferedImage rgbImage = new BufferedImage(
                            bufferedImage.getWidth(),
                            bufferedImage.getHeight(),
                            BufferedImage.TYPE_INT_RGB
                    );
                    Graphics2D g2d = rgbImage.createGraphics();
                    g2d.setColor(java.awt.Color.WHITE); // 白色背景
                    g2d.fillRect(0, 0, rgbImage.getWidth(), rgbImage.getHeight());
                    g2d.drawImage(bufferedImage, 0, 0, null);
                    g2d.dispose();

                    ImageIO.write(rgbImage, "jpg", file);
                } else {
                    ImageIO.write(bufferedImage, extension, file);
                }

                showSimpleAlert("导出成功: " + file.getAbsolutePath());
            } catch (IOException e) {
                showSimpleAlert("导出失败: " + e.getMessage());
            }
        }
    }



    private String currentFilePath;     // 当前文件路径

    //另存为
    @FXML
    private void handleResave(ActionEvent actionEvent) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("保存思维导图");
        fileChooser.getExtensionFilters().add(
                new FileChooser.ExtensionFilter("思维导图文件", "*.xmind"));

        // 显示文件保存对话框
        File file = fileChooser.showSaveDialog(canvasPane.getScene().getWindow());

        if (file != null) {
            try {
                String path = file.getAbsolutePath();
                if (!path.endsWith(".xmind")) {
                    path += ".xmind"; // 确保文件扩展名
                }
                MindMapPersistence.saveToFile(currentMap, path);
                currentFilePath = path; // 更新当前文件路径
                updateTitleFromPath(); // 新增标题更新方法
                showSimpleAlert("保存成功!");
            } catch (IOException e) {
                showSimpleAlert("保存失败: " + e.getMessage());
            }
        }

    }

    private void updateTitleFromPath() {
        if (currentFilePath != null && !currentFilePath.isEmpty()) {
            String fileName = new File(currentFilePath).getName()
                    .replace(".xmind", "");
            if (fileName.length() > 20) {
                fileName = fileName.substring(0, 17) + "...";
            }
            mapTitle.setText(fileName);
        }
    }

    //保存
    @FXML
    private void handleSave(ActionEvent actionEvent) {
        if (currentFilePath == null) {
            handleResave(actionEvent); // 未保存过则调用另存为
        } else {
            try {
                MindMapPersistence.saveToFile(currentMap, currentFilePath);
                updateTitleFromPath();
                showSimpleAlert("保存成功!");
            } catch (IOException e) {
                showSimpleAlert("保存失败: " + e.getMessage());
            }
        }

    }

    //打开
    @FXML
    private void handleOpen(ActionEvent actionEvent) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("打开思维导图");
        fileChooser.getExtensionFilters().add(
                new FileChooser.ExtensionFilter("思维导图文件", "*.xmind"));

        File file = fileChooser.showOpenDialog(canvasPane.getScene().getWindow());

        if (file != null) {
            try {
                currentMap = MindMapPersistence.loadFromFile(file.getAbsolutePath());
                currentFilePath = file.getAbsolutePath();
                selectedNode = currentMap.getRoot();
                updateTitleFromPath();
                refreshLayout();
            } catch (IOException e) {
                showSimpleAlert("打开失败: " + e.getMessage());
            }
        }
    }


    // 状态历史栈，方便撤销和重做
    private final Stack<MindMap> undoStack = new Stack<>();
    private final Stack<MindMap> redoStack = new Stack<>();

    // 在操作前调用，保存当前状态
    private void pushState() {
        // 深拷贝当前导图状态
        try {
            File tempFile = File.createTempFile("undo", ".xmind");
            MindMapPersistence.saveToFile(currentMap, tempFile.getAbsolutePath());
            MindMap copy = MindMapPersistence.loadFromFile(tempFile.getAbsolutePath());
            undoStack.push(copy);
            redoStack.clear(); // 新操作发生时，清空重做栈
        } catch (IOException e) {
            Log.showSimpleAlert("无法保存历史状态: " + e.getMessage());
        }
    }

    //重做
    @FXML
    private void handleRedo(ActionEvent actionEvent) {
        if (!redoStack.isEmpty()) {
            undoStack.push(cloneCurrentMap());
            currentMap = redoStack.pop();
            selectedNode = currentMap.getRoot(); // 重置选中节点
            refreshLayout();
        } else {
            Log.showSimpleAlert("没有可重做的操作");
        }
    }

    //撤销
    @FXML
    private void handleUndo(ActionEvent actionEvent) {
        if (!undoStack.isEmpty()) {
            redoStack.push(cloneCurrentMap());
            currentMap = undoStack.pop();
            selectedNode = currentMap.getRoot(); // 重置选中节点
            refreshLayout();
        } else {
            Log.showSimpleAlert("没有可撤销的操作");
        }
    }

    //拷贝当前导图，用于重做
    private MindMap cloneCurrentMap() {
        try {
            File tempFile = File.createTempFile("redo", ".xmind");
            MindMapPersistence.saveToFile(currentMap, tempFile.getAbsolutePath());
            return MindMapPersistence.loadFromFile(tempFile.getAbsolutePath());
        } catch (IOException e) {
            Log.showSimpleAlert("复制导图失败: " + e.getMessage());
            return currentMap;
        }
    }

}